package org.linlinjava.litemall.db.service;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import com.github.yulichang.base.MPJBaseServiceImpl;
import org.apache.ibatis.annotations.Select;
import org.linlinjava.litemall.db.beans.Constants;
import org.linlinjava.litemall.db.dao.LitemallCouponMapper;
import org.linlinjava.litemall.db.dao.LitemallCouponUserMapper;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.domain.LitemallCoupon.Column;
import org.linlinjava.litemall.db.util.CouponUserConstant;
import org.springframework.cglib.core.Local;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class LitemallCouponService {
    @Resource
    private LitemallCouponMapper couponMapper;
    @Resource
    private LitemallCouponUserMapper couponUserMapper;

    private Column[] result = new Column[]{Column.id, Column.name, Column.desc, Column.tag,
                                            Column.days, Column.startTime, Column.endTime,
                                            Column.discount, Column.min, Column.userLevel,Column.levelMemberType,Column.moneyMemberType,Column.total,Column.limit,Column.discountType,Column.discountRate,Column.pictureUrl,Column.surplus,Column.timeType};

    /**
     * 查询，空参数
     *criteria.andStatusEqualTo( 1);
     * @param offset
     * @param limit
     * @param sort
     * @param order
     * @return
     */
    public List<LitemallCoupon> queryList(int offset, int limit, String sort, String order) {
        return queryList(LitemallCouponExample.newAndCreateCriteria(), offset, limit, sort, order);
    }

    /**
     * 查询
     *
     * @param criteria 可扩展的条件
     * @param offset
     * @param limit
     * @param sort
     * @param order
     * @return
     */
    public List<LitemallCoupon> queryList(LitemallCouponExample.Criteria criteria, int offset, int limit, String sort, String order) {
        criteria.andTypeEqualTo(Constants.TYPE_REGISTER).andStatusEqualTo(Constants.Coupon_STATUS_PUSHED).andDeletedEqualTo(false);
//        criteria.andRangesEqualTo((short)1);
//        List<Short> ranges = new ArrayList<>(Arrays.asList(new Short[]{0,1}));
//        criteria.andRangesIn(ranges);
        criteria.example().setOrderByClause(sort + " " + order);


        return couponMapper.selectByExampleSelective(criteria.example(), result);
    }

    public List<LitemallCoupon> queryAvailableList(Integer userId, int offset, int limit) {
        assert userId != null;
        // 过滤掉登录账号已经领取过的coupon
        LitemallCouponExample.Criteria c = LitemallCouponExample.newAndCreateCriteria();

        List<Short> ranges = new ArrayList<>(Arrays.asList(new Short[]{0,1}));
        c.andRangesIn(ranges);


        return queryList(c, offset, limit, "add_time", "desc");
    }

    public List<LitemallCoupon> queryAllByRanges(Integer userId) {
        assert userId != null;
        return couponMapper.queryAllByRanges();
    }


    public List<LitemallCoupon> queryList(int offset, int limit) {
//        return couponMapper.selec
//        tList(Wrappers.lambdaQuery(LitemallCoupon.class)
//                .orderByAsc(LitemallCoupon::getAddTime));
        return queryList(offset, limit, "add_time", "asc").stream().filter(litemallCoupon -> litemallCoupon.getIsBirthdayUse()==1).collect(Collectors.toList());
    }

    public List<LitemallCoupon> queryListInApp(LitemallCouponExample.Criteria criteria, int offset, int limit, String sort, String order) {
        criteria.andTypeEqualTo(Constants.TYPE_REGISTER).andStatusEqualTo(Constants.Coupon_STATUS_PUSHED).andDeletedEqualTo(false);
//        criteria.andRangesEqualTo((short)1);
        List<Short> ranges = new ArrayList<>(Arrays.asList(new Short[]{0,1}));
        criteria.andRangesIn(ranges);
        criteria.example().setOrderByClause(sort + " " + order);
        criteria.andDeletedEqualTo(false);

        //PageHelper.startPage(offset, limit);
        return couponMapper.selectByExampleSelective(criteria.example(), result);
    }

    public LitemallCoupon findById(Integer id) {
        return couponMapper.selectByPrimaryKey(id);
    }

    public LitemallCoupon findByIdAndStatus(Integer id){
        LitemallCouponExample example = new LitemallCouponExample();
        example.or().andStatusEqualTo((short)1).andDeletedEqualTo(false).andIdEqualTo(id);
        return couponMapper.selectOneByExample(example);
    }

    public List<LitemallCoupon> getListByType(Short type){
        LitemallCouponExample example = new LitemallCouponExample();
        LitemallCouponExample.Criteria criteria = example.createCriteria();


        if(type != null){
            criteria.andTypeEqualTo(type);
        }

        return couponMapper.selectByExample(example);
    }


    public LitemallCoupon findByCode(String code) {
        LitemallCouponExample example = new LitemallCouponExample();
        List<Short> status = new ArrayList<>();
        status.add((short)1);
        status.add((short)3);
        example.or().andCodeEqualTo(code).andStatusIn(status).andDeletedEqualTo(false);
        List<LitemallCoupon> couponList =  couponMapper.selectByExample(example);
        if(couponList.size() > 1){
            throw new RuntimeException("POS不能使用这张APP专用");
        }
        else if(couponList.size() == 0){
            return null;
        }
        else {
            return couponList.get(0);
        }
    }

    public LitemallCoupon findByBarCode(String barCode) {
        LitemallCouponExample example = new LitemallCouponExample();
        example.or().andBarCodeEqualTo(barCode).andDeletedEqualTo(false);
        List<LitemallCoupon> couponList =  couponMapper.selectByExample(example);
        if(couponList.size() > 1){
            throw new RuntimeException("POS不能使用这张APP专用");
        }
        else if(couponList.size() == 0){
            return null;
        }
        else {
            return couponList.get(0);
        }
    }

    /**
     * 查询新用户注册优惠券
     *
     * @return
     */
    public List<LitemallCoupon> queryRegister() {
        LitemallCouponExample example = new LitemallCouponExample();
        example.or().andTypeEqualTo(Constants.TYPE_REGISTER).andStatusEqualTo(Constants.COUPON_STATUS_NORMAL).andDeletedEqualTo(false);
        return couponMapper.selectByExample(example);
    }

    public List<LitemallCoupon> querySelective(String name, Short type, Short lossBearing, Short status, Short areaLimit,
                                               Byte discountType, Integer page, Integer limit, String sort, String order,Short ranges,Boolean isExpired) {

        LitemallCouponExample example = new LitemallCouponExample();
        LitemallCouponExample.Criteria criteria = example.createCriteria();
        LitemallCouponExample.Criteria criteria1 = example.createCriteria();

        if (!StringUtils.isEmpty(name)) {
            criteria.andNameLike("%" + name + "%");
            criteria1.andNameLike("%" + name + "%");
        }

        if(lossBearing != null){
            criteria.andLossBearingEqualTo(lossBearing);
            criteria1.andLossBearingEqualTo(lossBearing);
        }

        if(isExpired){
            criteria.andStartTimeLessThan(LocalDateTime.now()).andEndTimeGreaterThan(LocalDateTime.now());
            criteria1.andTimeTypeEqualTo((short)0);
        }

        if (type != null) {
            criteria.andTypeEqualTo(type);
            criteria1.andTypeEqualTo(type);
        }

        if(discountType != null){
            criteria.andDiscountTypeEqualTo(discountType);
            criteria1.andTypeEqualTo(type);
        }

        if (status != null) {
            criteria.andStatusEqualTo(status);
            criteria1.andTypeEqualTo(type);
        }

        if(areaLimit != null){
            criteria.andAreaLimitEqualTo(areaLimit);
            criteria1.andTypeEqualTo(type);
        }

        /*if(ranges != null){
            criteria.andRangesEqualTo(Collections.singletonList(ranges));

        }*/

        criteria.andDeletedEqualTo(false);
        criteria1.andDeletedEqualTo(false);

        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
            example.setOrderByClause(sort + " " + order);
        }

        if(page != null &&  limit != null ){
            //PageHelper.startPage(page, limit);
        }
        return couponMapper.selectByExample(example);
    }

    public List<LitemallCoupon> querySelectiveInMember(  Integer page, Integer limit, String sort, String order,Boolean isExpired) {
        LitemallCouponExample example = new LitemallCouponExample();
        if(isExpired){
            example.or().andStartTimeLessThan(LocalDateTime.now()).andEndTimeGreaterThan(LocalDateTime.now()).andStatusEqualTo((short) 1).andTypeEqualTo((short) 3).andDeletedEqualTo(false).andTagEqualTo("3");
            example.or().andTimeTypeEqualTo((short)0).andStatusEqualTo((short) 1).andTypeEqualTo((short) 3).andDeletedEqualTo(false);
        }
        if (!StringUtils.isEmpty(sort) && !StringUtils.isEmpty(order)) {
            example.setOrderByClause(sort + " " + order);
        }
        if(page != null &&  limit != null ){
            //PageHelper.startPage(page, limit);
        }
        return couponMapper.selectByExample(example);
    }

    public void add(LitemallCoupon coupon) {
        coupon.setAddTime(LocalDateTime.now());
        coupon.setUpdateTime(LocalDateTime.now());
        coupon.setStatus(CouponUserConstant.STATUS_USABLE);
        couponMapper.insertSelective(coupon);
    }

    public int updateById(LitemallCoupon coupon) {
        coupon.setUpdateTime(LocalDateTime.now());
        return couponMapper.updateByPrimaryKeySelective(coupon);
    }

    public int update(LitemallCoupon coupon) {
        coupon.setUpdateTime(LocalDateTime.now());
        return couponMapper.update(coupon);
    }

    public void deleteById(Integer id) {
        couponMapper.logicalDeleteByPrimaryKey(id);
    }

    private String getRandomNum(Integer num) {
        String base = "0123456789";

        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < num; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    /**
     * 生成优惠码
     *
     * @return 可使用优惠码
     */
    public String generateCode() {
        String code = getRandomNum(8);
        while(findByCode(code) != null){
            code = getRandomNum(8);
        }
        return code;
    }


    /**
     * 生成优惠券码
     *
     * @return 可使用优惠券码
     */
    public String generateCouponCode() {
        String code = getRandomNum(8);
        while(findByCode(code) != null){
            code = getRandomNum(8);
        }
        return code;
    }

    /**
     * 查询过期的优惠券:
     * 注意：如果timeType=0, 即基于领取时间有效期的优惠券，则优惠券不会过期
     *
     * @return
     */
    public List<LitemallCoupon> queryExpired() {
        LitemallCouponExample example = new LitemallCouponExample();
        example.or().andStatusEqualTo(Constants.COUPON_PUSHED).andEndTimeLessThan(LocalDateTime.now()).andDeletedEqualTo(false);
        return couponMapper.selectByExample(example);
    }

    public int queryUserCouponCount(Integer userId) {
        LitemallCouponUserExample example = new LitemallCouponUserExample();
        LitemallCouponUserExample.Criteria criteria = example.or();

        criteria.andUserIdEqualTo(userId);
        criteria.andStatusEqualTo(Short.valueOf("0"));
        return (int)couponUserMapper.countByExample(example);
    }

    public List<LitemallCoupon> queryAll(Integer type){

        LitemallCouponExample example = new LitemallCouponExample();
        LitemallCouponExample.Criteria criteria = example.or().andDeletedEqualTo(false);

        if(type != null) {
            criteria.andTypeEqualTo(type.shortValue());
        }
        criteria.andDeletedEqualTo(false);
//        criteria.andEndTimeGreaterThan(LocalDateTime.now());
        return couponMapper.selectByExample(example);
    }

    public List<LitemallCoupon> queryAllInGener(Integer type,Integer page,Integer limit){

        LitemallCouponExample example = new LitemallCouponExample();
        LitemallCouponExample.Criteria criteria = example.or().andDeletedEqualTo(false);

        if(type != null) {
            criteria.andTypeEqualTo(type.shortValue());
        }
        criteria.andDeletedEqualTo(false);

        if(page!=null && limit != null){
            //PageHelper.startPage(page, limit);
        }

        return couponMapper.selectByExample(example);
    }

//    public List<LitemallCoupon> queryByStatus(Integer status,)
}
